home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / JFC.bin / JProgressBar.java < prev    next >
Text File  |  1998-06-30  |  17KB  |  547 lines

  1. /*
  2.  * @(#)JProgressBar.java    1.49 98/04/07
  3.  * 
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  */
  20.  
  21. package com.sun.java.swing;
  22.  
  23. import java.awt.Color;
  24. import java.awt.Graphics;
  25. import com.sun.java.swing.event.*;
  26. import com.sun.java.accessibility.*;
  27. import java.io.Serializable;
  28. import com.sun.java.swing.plaf.ProgressBarUI;
  29.  
  30.  
  31. /**
  32.  * A component that displays an integer value graphically within a bounded 
  33.  * interval. A progress bar typically communicates the progress of an 
  34.  * event by displaying its percentage of completion. The orientation of 
  35.  * the progress bar depends on its size. If its height is greater than
  36.  * its width, the progress bar is vertical.
  37.  * <p>
  38.  * Warning: serialized objects of this class will not be compatible with
  39.  * future swing releases.  The current serialization support is appropriate
  40.  * for short term storage or RMI between Swing1.0 applications.  It will
  41.  * not be possible to load serialized Swing1.0 objects with future releases
  42.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  43.  * baseline for the serialized form of Swing objects.
  44.  *
  45.  * @beaninfo
  46.  *      attribute: isContainer false
  47.  *    description:  A component that displays an integer value graphically.
  48.  *
  49.  * @version 1.49 04/07/98
  50.  * @author Rob Davis
  51.  */
  52. public class JProgressBar extends JComponent implements SwingConstants, Accessible
  53. {
  54.     protected int orientation;
  55.     protected boolean paintBorder;
  56.     protected BoundedRangeModel barModel;
  57.  
  58.  
  59.     /**
  60.      * Only one ChangeEvent is needed per instance since the
  61.      * event's only interesting property is the immutable source, which
  62.      * is the progress bar.
  63.      */
  64.     protected transient ChangeEvent changeEvent = null;
  65.     protected ChangeListener changeListener = null;
  66.  
  67.     /**
  68.      * Creates a horizontal progress bar with a border.
  69.      */
  70.     public JProgressBar()
  71.     {
  72.         setModel(new DefaultBoundedRangeModel());
  73.         updateUI();
  74.  
  75.         orientation = HORIZONTAL;  // documented with set/getOrientation()
  76.         paintBorder = true;        // documented with is/setBorderPainted()
  77.     }
  78.  
  79.     /**
  80.      * Overridden to call paint without filling the background.
  81.      */
  82.     public void update(Graphics g) {
  83.         this.paint(g);
  84.     }
  85.  
  86.     /**
  87.      * Returns <code>JProgressBar.VERTICAL</code> or 
  88.      * <code>JProgressBar.HORIZONTAL</code>, depending on the orientation
  89.      * of the progress bar. The default orientation is 
  90.      * <code>HORIZONTAL</code>.
  91.      *
  92.      * @return HORIZONTAL or VERTICAL
  93.      */
  94.     public int getOrientation() {
  95.         return orientation;
  96.     }
  97.  
  98.     /**
  99.      * Sets the progress bar's orientation to <I>newOrientation</I>, which
  100.      * must be <code>JProgressBar.VERTICAL</code> or 
  101.      * <code>JProgressBar.HORIZONTAL</code>. The default orientation 
  102.      * is <code>HORIZONTAL</code>.
  103.      *
  104.      * @param  newOrientation  HORIZONTAL or VERTICAL
  105.      * @exception      IllegalArgumentException    if <I>newOrientation</I>
  106.      *                                              is an illegal value
  107.      * @beaninfo
  108.      *    preferred: true
  109.      *  description: The progress bar's orientation.
  110.      */
  111.     public void setOrientation(int newOrientation) {
  112.         if (orientation != newOrientation) {
  113.             switch (newOrientation) {
  114.             case VERTICAL:
  115.             case HORIZONTAL:
  116.                 int oldorientation = orientation;
  117.                 orientation = newOrientation;
  118.                 if (accessibleContext != null) {
  119.                     accessibleContext.firePropertyChange(
  120.                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  121.                             ((oldorientation == VERTICAL) 
  122.                  ? AccessibleState.VERTICAL 
  123.                  : AccessibleState.HORIZONTAL),
  124.                             ((orientation == VERTICAL) 
  125.                  ? AccessibleState.VERTICAL 
  126.                  : AccessibleState.HORIZONTAL));
  127.             }
  128.                 break;
  129.             default:
  130.                 throw new IllegalArgumentException(newOrientation +
  131.                                              " is not a legal orientation");
  132.             }
  133.             repaint();
  134.         }
  135.     }
  136.  
  137.     /**
  138.      * Returns true if the progress bar has a border or false if it does not.
  139.      *
  140.      * @return whether the progress bar has a border
  141.      * @see    setBorderPainted
  142.      */
  143.     public boolean isBorderPainted() {
  144.         return paintBorder;
  145.     }
  146.  
  147.     /**
  148.      * Sets whether the progress bar should have a border.
  149.      *
  150.      * @param   b       true if the progress bar should have a border
  151.      * @see     isBorderPainted
  152.      * @beaninfo
  153.      *  description: Whether the progress bar should have a border.
  154.      */
  155.     public void setBorderPainted(boolean b) {
  156.         paintBorder = b;
  157.         repaint();
  158.     }
  159.  
  160.     /**
  161.      * Paint the progress bar's border if BorderPainted property is true.
  162.      * 
  163.      * @param g  the Graphics context within which to paint the border
  164.      * @see #paint
  165.      * @see #setBorder
  166.      */
  167.     protected void paintBorder(Graphics g) {    
  168.         if (isBorderPainted()) {
  169.             super.paintBorder(g);
  170.         }
  171.     }
  172.  
  173.  
  174.     /**
  175.      * Returns the L&F object that renders this component.
  176.      *
  177.      * @return the ProgressBarUI object that renders this component
  178.      */
  179.     public ProgressBarUI getUI() {
  180.         return (ProgressBarUI)ui;
  181.     }
  182.  
  183.     /**
  184.      * Sets the L&F object that renders this component.
  185.      *
  186.      * @param ui  the ProgressBarUI L&F object
  187.      * @see UIDefaults#getUI
  188.      * @beaninfo
  189.      *       expert: true
  190.      *  description: The ProgressBarUI implementation that defines the combo box look and feel.
  191.      */
  192.     public void setUI(ProgressBarUI ui) {
  193.         if (this.ui != ui) {
  194.             super.setUI(ui);
  195.             repaint();
  196.         }
  197.     }
  198.  
  199.  
  200.     /**
  201.      * Notification from the UIFactory that the L&F has changed. 
  202.      * Called to replace the UI with the latest version from the 
  203.      * UIFactory.
  204.      *
  205.      * @see JComponent#updateUI
  206.      */
  207.     public void updateUI() {
  208.         setUI((ProgressBarUI)UIManager.getUI(this));
  209.     }
  210.  
  211.  
  212.     /**
  213.      * Returns the name of the L&F class that renders this component.
  214.      *
  215.      * @return "ProgressBarUI"
  216.      * @see JComponent#getUIClassID
  217.      * @see UIDefaults#getUI
  218.      * @beaninfo
  219.      *        expert: true
  220.      *   description: A string that specifies the name of the L&F class.
  221.      */
  222.     public String getUIClassID() {
  223.         return "ProgressBarUI";
  224.     }
  225.  
  226.  
  227.     /* We pass each Change event to the listeners with the
  228.      * the progress bar as the event source.
  229.      * <p>
  230.      * Warning: serialized objects of this class will not be compatible with
  231.      * future swing releases.  The current serialization support is appropriate
  232.      * for short term storage or RMI between Swing1.0 applications.  It will
  233.      * not be possible to load serialized Swing1.0 objects with future releases
  234.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  235.      * baseline for the serialized form of Swing objects.
  236.      */
  237.     protected class ModelListener implements ChangeListener, Serializable {
  238.         public void stateChanged(ChangeEvent e) {
  239.             fireStateChanged();
  240.         }
  241.     }
  242.  
  243.     /* Subclasses that want to handle ChangeEvents differently
  244.      * can override this to return a subclass of ModelListener or
  245.      * another ChangeListener implementation.
  246.      */
  247.     protected ChangeListener createChangeListener() {
  248.         return new ModelListener();
  249.     }
  250.  
  251.     /**
  252.      * Adds a ChangeListener to the button.
  253.      *
  254.      * @param l the ChangeListener to add
  255.      */
  256.     public void addChangeListener(ChangeListener l) {
  257.         listenerList.add(ChangeListener.class, l);
  258.     }
  259.     
  260.     /**
  261.      * Removes a ChangeListener from the button.
  262.      *
  263.      * @param l the ChangeListener to remove
  264.      */
  265.     public void removeChangeListener(ChangeListener l) {
  266.         listenerList.remove(ChangeListener.class, l);
  267.     }
  268.         
  269.     /**
  270.      * Notify all listeners that have registered interest for
  271.      * notification on this event type.  The event instance 
  272.      * is lazily created using the parameters passed into 
  273.      * the fire method.
  274.      * @see EventListenerList
  275.      */
  276.     protected void fireStateChanged() {
  277.         // Guaranteed to return a non-null array
  278.         Object[] listeners = listenerList.getListenerList();
  279.         // Process the listeners last to first, notifying
  280.         // those that are interested in this event
  281.         for (int i = listeners.length-2; i>=0; i-=2) {
  282.             if (listeners[i]==ChangeListener.class) {
  283.                 // Lazily create the event:
  284.                 if (changeEvent == null)
  285.                     changeEvent = new ChangeEvent(this);
  286.                 ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
  287.             }          
  288.         }
  289.     } 
  290.       
  291.     /**
  292.      * Returns the data model used by the JProgressBar.
  293.      *
  294.      * @return the BoundedRangeModel currently in use
  295.      * @see    BoundedRangeModel
  296.      */
  297.     public BoundedRangeModel getModel() {
  298.         return barModel;
  299.     }
  300.  
  301.     /**
  302.      * Sets the data model used by the JProgressBar.
  303.      *
  304.      * @param  newModel the BoundedRangeModel to use
  305.      * @see    BoundedRangeModel
  306.      * @beaninfo
  307.      *    expert: true
  308.      * description: The data model used by the JProgressBar.
  309.      */
  310.     public void setModel(BoundedRangeModel newModel) {
  311.         // PENDING(???) setting the same model to multiple bars is broken; listeners
  312.         BoundedRangeModel oldModel = getModel();
  313.  
  314.         if (newModel != oldModel) {
  315.             if (oldModel != null) {
  316.                 oldModel.removeChangeListener(changeListener);
  317.                 changeListener = null;
  318.             }
  319.  
  320.             barModel = newModel;
  321.  
  322.             if (newModel != null) {
  323.                 changeListener = createChangeListener();
  324.                 newModel.addChangeListener(changeListener);
  325.             }
  326.  
  327.         if (accessibleContext != null) {
  328.                 accessibleContext.firePropertyChange(
  329.                 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
  330.                         (oldModel== null 
  331.              ? null : new Integer(oldModel.getValue())),
  332.                         (newModel== null 
  333.              ? null : new Integer(newModel.getValue())));
  334.         }
  335.  
  336.             barModel.setExtent(0);
  337.             repaint();
  338.         }
  339.     }
  340.  
  341.  
  342.     /* All of the model methods are implemented by delegation. */
  343.  
  344.     /**
  345.      * Returns the model's current value. The value is always between the 
  346.      * model's minimum and maximum values, inclusive.
  347.      *
  348.      * @return  the value
  349.      * @see     #setValue
  350.      * @see     BoundedRangeModel
  351.      */
  352.     public int getValue() { return getModel().getValue(); }
  353.  
  354.     /**
  355.      * Returns the model's minimum value.
  356.      *
  357.      * @return  an int -- the model's minimum
  358.      * @see     #setMinimum
  359.      * @see     BoundedRangeModel
  360.      */
  361.     public int getMinimum() { return getModel().getMinimum(); }
  362.  
  363.     /**
  364.      * Returns the model's maximum value.
  365.      *
  366.      * @return  an int -- the model's maximum
  367.      * @see     #setMaximum
  368.      * @see     BoundedRangeModel
  369.      */
  370.     public int getMaximum() { return getModel().getMaximum(); }
  371.  
  372.     /**
  373.      * Sets the model's current value to <I>x</I>. If <I>x</I> is less than the
  374.      * minimum or greater than the maximum, this method throws an
  375.      * <code>IllegalArgumentException</code> and the value is not changed.
  376.      * <p>
  377.      * Notifies any listeners if the data changes.
  378.      *
  379.      * @param   x       the new value
  380.      * @see     #getValue
  381.      * @see     BoundedRangeModel
  382.      * @beaninfo
  383.      *    preferred: true
  384.      *  description: The model's current value.
  385.      */
  386.     public void setValue(int n) { 
  387.         BoundedRangeModel brm = getModel();
  388.     int oldValue = brm.getValue();
  389.  
  390.     brm.setValue(n);
  391.  
  392.     if (accessibleContext != null) {
  393.             accessibleContext.firePropertyChange(
  394.             AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
  395.                     new Integer(oldValue),
  396.                     new Integer(brm.getValue()));
  397.     }
  398.     }
  399.  
  400.     /**
  401.      * Sets the model's minimum to <I>x</I>. If the maximum value or
  402.      * current value is outside of the new minimum, the maximum or 
  403.      * current value is adjusted accordingly.
  404.      * <p>
  405.      * Notifies any listeners if the data changes.
  406.      *
  407.      * @param  x       the new minimum
  408.      * @see    #getMinimum
  409.      * @see    #addChangeListener
  410.      * @see    BoundedRangeModel
  411.      * @beaninfo
  412.      *  preferred: true
  413.      * description: The model's minimum value.
  414.      */
  415.     public void setMinimum(int n) { getModel().setMinimum(n); }
  416.  
  417.     /**
  418.      * Sets the model's maximum to <I>x</I>. If the minimum value or
  419.      * current value is outside of the new maximum, the minimum or 
  420.      * current value is adjusted accordingly.
  421.      * <p>
  422.      * Notifies any listeners if the data changes.
  423.      *
  424.      * @param  x       the new maximum
  425.      * @see    #getMaximum
  426.      * @see    #addChangeListener
  427.      * @see    BoundedRangeModel
  428.      * @beaninfo
  429.      *    preferred: true
  430.      *  description: The model's maximum value.
  431.      */
  432.     public void setMaximum(int n) { getModel().setMaximum(n); }
  433.  
  434. /////////////////
  435. // Accessibility support
  436. ////////////////
  437.  
  438.     /**
  439.      * Get the AccessibleContext associated with this JComponent
  440.      *
  441.      * @return the AccessibleContext of this JComponent
  442.      * @beaninfo
  443.      *       expert: true
  444.      *  description: The AccessibleContext associated with this ProgressBar.
  445.      */
  446.     public AccessibleContext getAccessibleContext() {
  447.         if (accessibleContext == null) {
  448.             accessibleContext = new AccessibleJProgressBar();
  449.         }
  450.         return accessibleContext;
  451.     }
  452.  
  453.     /**
  454.      * The class used to obtain the accessible role for this object.
  455.      * <p>
  456.      * Warning: serialized objects of this class will not be compatible with
  457.      * future swing releases.  The current serialization support is appropriate
  458.      * for short term storage or RMI between Swing1.0 applications.  It will
  459.      * not be possible to load serialized Swing1.0 objects with future releases
  460.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  461.      * baseline for the serialized form of Swing objects.
  462.      */
  463.     protected class AccessibleJProgressBar extends AccessibleJComponent
  464.         implements AccessibleValue {
  465.  
  466.         /**
  467.          * Get the state set of this object.
  468.          *
  469.          * @return an instance of AccessibleState containing the current state 
  470.          * of the object
  471.          * @see AccessibleState
  472.          */
  473.         public AccessibleStateSet getAccessibleStateSet() {
  474.             AccessibleStateSet states = super.getAccessibleStateSet();
  475.             if (getModel().getValueIsAdjusting()) {
  476.                 states.add(AccessibleState.BUSY);
  477.             }
  478.             if (getOrientation() == VERTICAL) {
  479.                 states.add(AccessibleState.VERTICAL);
  480.             } else {
  481.                 states.add(AccessibleState.HORIZONTAL);
  482.             }
  483.             return states;
  484.         }
  485.  
  486.         /**
  487.          * Get the role of this object.
  488.          *
  489.          * @return an instance of AccessibleRole describing the role of the 
  490.          * object
  491.          */
  492.         public AccessibleRole getAccessibleRole() {
  493.             return AccessibleRole.PROGRESS_BAR;
  494.         }
  495.  
  496.         /**
  497.          * Get the AccessibleValue associated with this object if one
  498.          * exists.  Otherwise return null.
  499.          */
  500.         public AccessibleValue getAccessibleValue() {
  501.             return this;
  502.         }
  503.  
  504.         /**
  505.          * Get the accessible value of this object.
  506.          *
  507.          * @return The current value of this object.
  508.          */
  509.         public Number getCurrentAccessibleValue() {
  510.             return new Integer(getValue());
  511.         }
  512.  
  513.         /**
  514.          * Set the value of this object as a Number.
  515.          *
  516.          * @return True if the value was set.
  517.          */
  518.         public boolean setCurrentAccessibleValue(Number n) {
  519.             if (n instanceof Integer) {
  520.                 setValue(n.intValue());
  521.                 return true;
  522.             } else {
  523.                 return false;
  524.             }
  525.         }
  526.  
  527.         /**
  528.          * Get the minimum accessible value of this object.
  529.          *
  530.          * @return The minimum value of this object.
  531.          */
  532.         public Number getMinimumAccessibleValue() {
  533.             return new Integer(getMinimum());
  534.         }
  535.  
  536.         /**
  537.          * Get the maximum accessible value of this object.
  538.          *
  539.          * @return The maximum value of this object.
  540.          */
  541.         public Number getMaximumAccessibleValue() {
  542.             return new Integer(getMaximum());
  543.         }
  544.  
  545.     } // AccessibleJProgressBar
  546. }
  547.